﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using bxml.betterxml.xir;

namespace bxml.betterxml.parsers
{

    public class XIRParser : BetterXmlParser
    {
        private BetterXmlContentHandler handler;

        public void parse(StreamReader input)
        {
            XIRReader reader = new XIRReader(input);
            XIRDataObject xir;

            while (true)
            {
                xir = reader.getNextRecord();
                if (xir == null) break;
                XIRDataObjectTypes type = xir.getType();
                if (type == XIRDataObjectTypes.None)
                    continue;
                XIRDataObjectSubtypes subtype = xir.getSubtype();

                switch (type)
                {
                    case XIRDataObjectTypes.Document:
                        {
                            if (subtype == XIRDataObjectSubtypes.Begin)
                                handler.startDocument();
                            else
                            {
                                handler.endDocument();
                                return;
                            }
                            break;
                        }
                    case XIRDataObjectTypes.PrefixMapping:
                        {
                            String prefix = xir.getValue("prefix");
                            String uri = xir.getValue("uri");
                            if (subtype == XIRDataObjectSubtypes.Begin)
                                handler.startPrefixMapping(prefix, uri);
                            else
                                handler.endPrefixMapping(prefix);
                            break;
                        }
                    case XIRDataObjectTypes.Element:
                        {
                            if (subtype == XIRDataObjectSubtypes.Begin)
                            {
                                String attributes = xir.getValue("attributes");
                                String ns = xir.getValue("ns");
                                String name = xir.getValue("name");
                                String qname = xir.getValue("qname");
                                handler.startElement(ns, name, qname, int.Parse(attributes));
                            }
                            else
                            {
                                String ns = xir.getValue("ns");
                                String name = xir.getValue("name");
                                String qname = xir.getValue("qname");
                                handler.endElement(ns, name, qname);
                            }
                            break;
                        }
                    case XIRDataObjectTypes.Attribute:
                        {
                            String ns = xir.getValue("ns");
                            String name = xir.getValue("name");
                            String value = xir.getValue("value");
                            String qname = xir.getValue("qname");
                            handler.attribute(ns, name, qname, value);
                            break;
                        }
                    case XIRDataObjectTypes.Characters:
                        {
                            String cdata = xir.getValue("cdata");
                            handler.characters(cdata.Length, cdata);
                            break;
                        }
                    case XIRDataObjectTypes.Whitespace:
                        {
                            String cdata = xir.getValue("cdata");
                            handler.whitespace(cdata.Length, cdata);
                            break;
                        }
                    case XIRDataObjectTypes.SkippedEntity:
                        {
                            String name = xir.getValue("name");
                            handler.skippedEntity(name);
                            break;
                        }
                    case XIRDataObjectTypes.ProcessingInstruction:
                        {
                            String name = xir.getValue("name");
                            String target = xir.getValue("target");
                            handler.processingInstruction(name, target);
                            break;
                        }
                }

            }
        }

        public BetterXmlContentHandler getContentHandler()
        {
            return handler;
        }

        public BetterXmlParser setContentHandler(BetterXmlContentHandler handler)
        {
            this.handler = handler;
            return this;
        }
    }

}
